<!doctype html>
<html lang="zh-CN">
<head>
  <base href="https://www.nodeapp.cn/events.html" />
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>事件（Events） | Node.js 中文文档 | Node.js 中文网</title>
  <meta name="description" content="Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型，使其轻量又高效。Node.js 的包管理器 npm，是全球最大的开源库生态系统。">
  <link rel="stylesheet" href="assets/style.css">
  <link rel="stylesheet" href="assets/sh.css">
  <link rel="canonical" href="https://www.nodeapp.cn/events.html">
  <link rel="apple-touch-icon" href="apple-touch-icon.png">
  <link rel="icon" sizes="32x32" type="image/png" href="favicon.png">
  
  <script>
var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?acdf78480f7f8f2b23b812565a5868e0";
  var s = document.getElementsByTagName("script")[0]; 
  s.parentNode.insertBefore(hm, s);
})();
</script>

</head>
<body class="alt apidoc" id="api-section-events">
  <div id="content" class="clearfix">
    <div id="column1" data-id="events" class="interior">
      <header>
        <h1>Node.js v8.x 中文文档</h1>
        <hr>
      </header>

      <div id="toc">
        <h2>目录</h2>
        <ul>
<li><span class="stability_2"><a href="#events_events">events (事件)</a></span><ul>
<li><span class="stability_undefined"><a href="#events_passing_arguments_and_this_to_listeners">给监听器传入参数与 <code>this</code></a></span></li>
<li><span class="stability_undefined"><a href="#events_asynchronous_vs_synchronous">异步与同步</a></span></li>
<li><span class="stability_undefined"><a href="#events_handling_events_only_once">只处理事件一次</a></span></li>
<li><span class="stability_undefined"><a href="#events_error_events">错误事件</a></span></li>
<li><span class="stability_undefined"><a href="#events_class_eventemitter">EventEmitter 类</a></span><ul>
<li><span class="stability_undefined"><a href="#events_event_newlistener">&apos;newListener&apos; 事件</a></span></li>
<li><span class="stability_undefined"><a href="#events_event_removelistener">&apos;removeListener&apos; 事件</a></span></li>
<li><span class="stability_0"><a href="#events_eventemitter_listenercount_emitter_eventname">EventEmitter.listenerCount(emitter, eventName)</a></span></li>
<li><span class="stability_undefined"><a href="#events_eventemitter_defaultmaxlisteners">EventEmitter.defaultMaxListeners</a></span></li>
<li><span class="stability_undefined"><a href="#events_emitter_addlistener_eventname_listener">emitter.addListener(eventName, listener)</a></span></li>
<li><span class="stability_undefined"><a href="#events_emitter_emit_eventname_args">emitter.emit(eventName[, ...args])</a></span></li>
<li><span class="stability_undefined"><a href="#events_emitter_eventnames">emitter.eventNames()</a></span></li>
<li><span class="stability_undefined"><a href="#events_emitter_getmaxlisteners">emitter.getMaxListeners()</a></span></li>
<li><span class="stability_undefined"><a href="#events_emitter_listenercount_eventname">emitter.listenerCount(eventName)</a></span></li>
<li><span class="stability_undefined"><a href="#events_emitter_listeners_eventname">emitter.listeners(eventName)</a></span></li>
<li><span class="stability_undefined"><a href="#events_emitter_on_eventname_listener">emitter.on(eventName, listener)</a></span></li>
<li><span class="stability_undefined"><a href="#events_emitter_once_eventname_listener">emitter.once(eventName, listener)</a></span></li>
<li><span class="stability_undefined"><a href="#events_emitter_prependlistener_eventname_listener">emitter.prependListener(eventName, listener)</a></span></li>
<li><span class="stability_undefined"><a href="#events_emitter_prependoncelistener_eventname_listener">emitter.prependOnceListener(eventName, listener)</a></span></li>
<li><span class="stability_undefined"><a href="#events_emitter_removealllisteners_eventname">emitter.removeAllListeners([eventName])</a></span></li>
<li><span class="stability_undefined"><a href="#events_emitter_removelistener_eventname_listener">emitter.removeListener(eventName, listener)</a></span></li>
<li><span class="stability_undefined"><a href="#events_emitter_setmaxlisteners_n">emitter.setMaxListeners(n)</a></span></li>
</ul>
</li>
</ul>
</li>
</ul>

      </div>
<div id="apicontent">
        <h1>events (事件)<span><a class="mark" href="#events_events" id="events_events">#</a></span></h1>
<!--introduced_in=v0.10.0-->
<div class="api_stability api_stability_2"><a href="documentation.html#documentation_stability_index">稳定性: 2</a> - 稳定的</div><!--type=module-->
<p>大多数 Node.js 核心 API 都采用惯用的异步事件驱动架构，其中某些类型的对象（触发器）会周期性地触发命名事件来调用函数对象（监听器）。</p>
<p>例如，<a href="net.html#net_class_net_server"><code>net.Server</code></a> 对象会在每次有新连接时触发事件；<a href="fs.html#fs_class_fs_readstream"><code>fs.ReadStream</code></a> 会在文件被打开时触发事件；<a href="stream.html">流对象</a> 会在数据可读时触发事件。</p>
<p>所有能触发事件的对象都是 <code>EventEmitter</code> 类的实例。
这些对象开放了一个 <code>eventEmitter.on()</code> 函数，允许将一个或多个函数绑定到会被对象触发的命名事件上。
事件名称通常是驼峰式的字符串，但也可以使用任何有效的 JavaScript 属性名。</p>
<p>当 <code>EventEmitter</code> 对象触发一个事件时，所有绑定在该事件上的函数都被同步地调用。
监听器的返回值会被丢弃。</p>
<p>例子，一个绑定了一个监听器的 <code>EventEmitter</code> 实例。
<code>eventEmitter.on()</code> 方法用于注册监听器，<code>eventEmitter.emit()</code> 方法用于触发事件。</p>
<pre><code class="lang-js">const EventEmitter = require(&apos;events&apos;);

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter();
myEmitter.on(&apos;event&apos;, () =&gt; {
  console.log(&apos;触发了一个事件！&apos;);
});
myEmitter.emit(&apos;event&apos;);
</code></pre>
<h2>给监听器传入参数与 <code>this</code><span><a class="mark" href="#events_passing_arguments_and_this_to_listeners" id="events_passing_arguments_and_this_to_listeners">#</a></span></h2>
<p><code>eventEmitter.emit()</code> 方法允许将任意参数传给监听器函数。
当一个普通的监听器函数被 <code>EventEmitter</code> 调用时，标准的 <code>this</code> 关键词会被设置指向监听器所附加的 <code>EventEmitter</code>。</p>
<pre><code class="lang-js">const myEmitter = new MyEmitter();
myEmitter.on(&apos;event&apos;, function(a, b) {
  console.log(a, b, this);
  // 打印:
  //   a b MyEmitter {
  //     domain: null,
  //     _events: { event: [Function] },
  //     _eventsCount: 1,
  //     _maxListeners: undefined }
});
myEmitter.emit(&apos;event&apos;, &apos;a&apos;, &apos;b&apos;);
</code></pre>
<p>也可以使用 ES6 的箭头函数作为监听器。但是这样 <code>this</code> 关键词就不再指向 <code>EventEmitter</code> 实例：</p>
<pre><code class="lang-js">const myEmitter = new MyEmitter();
myEmitter.on(&apos;event&apos;, (a, b) =&gt; {
  console.log(a, b, this);
  // 打印: a b {}
});
myEmitter.emit(&apos;event&apos;, &apos;a&apos;, &apos;b&apos;);
</code></pre>
<h2>异步与同步<span><a class="mark" href="#events_asynchronous_vs_synchronous" id="events_asynchronous_vs_synchronous">#</a></span></h2>
<p><code>EventEmitter</code> 会按照监听器注册的顺序同步地调用所有监听器。
所以需要确保事件的正确排序且避免竞争条件或逻辑错误。
监听器函数可以使用 <code>setImmediate()</code> 或 <code>process.nextTick()</code> 方法切换到异步操作模式：</p>
<pre><code class="lang-js">const myEmitter = new MyEmitter();
myEmitter.on(&apos;event&apos;, (a, b) =&gt; {
  setImmediate(() =&gt; {
    console.log(&apos;这个是异步发生的&apos;);
  });
});
myEmitter.emit(&apos;event&apos;, &apos;a&apos;, &apos;b&apos;);
</code></pre>
<h2>只处理事件一次<span><a class="mark" href="#events_handling_events_only_once" id="events_handling_events_only_once">#</a></span></h2>
<p>当使用 <code>eventEmitter.on()</code> 方法注册监听器时，监听器会在每次触发命名事件时被调用。</p>
<pre><code class="lang-js">const myEmitter = new MyEmitter();
let m = 0;
myEmitter.on(&apos;event&apos;, () =&gt; {
  console.log(++m);
});
myEmitter.emit(&apos;event&apos;);
// 打印: 1
myEmitter.emit(&apos;event&apos;);
// 打印: 2
</code></pre>
<p>使用 <code>eventEmitter.once()</code> 方法时可以注册一个对于特定事件最多被调用一次的监听器。
当事件被触发时，监听器会被注销，然后再调用。</p>
<pre><code class="lang-js">const myEmitter = new MyEmitter();
let m = 0;
myEmitter.once(&apos;event&apos;, () =&gt; {
  console.log(++m);
});
myEmitter.emit(&apos;event&apos;);
// 打印: 1
myEmitter.emit(&apos;event&apos;);
// 忽略
</code></pre>
<h2>错误事件<span><a class="mark" href="#events_error_events" id="events_error_events">#</a></span></h2>
<p>当 <code>EventEmitter</code> 实例中发生错误时，会触发一个 <code>&apos;error&apos;</code> 事件。
这在 Node.js 中是特殊情况。</p>
<p>如果 <code>EventEmitter</code> 没有为 <code>&apos;error&apos;</code> 事件注册至少一个监听器，则当 <code>&apos;error&apos;</code> 事件触发时，会抛出错误、打印堆栈跟踪、且退出 Node.js 进程。</p>
<pre><code class="lang-js">const myEmitter = new MyEmitter();
myEmitter.emit(&apos;error&apos;, new Error(&apos;whoops!&apos;));
// 抛出错误，并使 Node.js 崩溃
</code></pre>
<p>为了防止 Node.js 进程崩溃，可以在使用 <a href="domain.html"><code>domain</code></a> 模块。
（注意，<code>domain</code> 模块已被废弃。）</p>
<p>作为最佳实践，应该始终为 <code>&apos;error&apos;</code> 事件注册监听器。</p>
<pre><code class="lang-js">const myEmitter = new MyEmitter();
myEmitter.on(&apos;error&apos;, (err) =&gt; {
  console.error(&apos;有错误&apos;);
});
myEmitter.emit(&apos;error&apos;, new Error(&apos;whoops!&apos;));
// 打印: 有错误
</code></pre>
<h2>EventEmitter 类<span><a class="mark" href="#events_class_eventemitter" id="events_class_eventemitter">#</a></span></h2>
<div class="api_metadata">
<span>新增于: v0.1.26</span>
</div><p><code>EventEmitter</code> 类由 <code>events</code> 模块定义和开放的：</p>
<pre><code class="lang-js">const EventEmitter = require(&apos;events&apos;);
</code></pre>
<p>当新的监听器被添加时，所有的 EventEmitter 会触发 <code>&apos;newListener&apos;</code> 事件；当移除已存在的监听器时，则触发 <code>&apos;removeListener&apos;</code>。</p>
<h3>&apos;newListener&apos; 事件<span><a class="mark" href="#events_event_newlistener" id="events_event_newlistener">#</a></span></h3>
<div class="api_metadata">
<span>新增于: v0.1.26</span>
</div><ul>
<li><code>eventName</code> <span class="type">&lt;any&gt;</span> 要监听的事件的名称</li>
<li><code>listener</code> 
            <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function" class="type">&lt;Function&gt;</a> 事件的句柄函数</li>
</ul>
<p><code>EventEmitter</code> 实例会在一个监听器被添加到其内部监听器数组之前触发自身的 <code>&apos;newListener&apos;</code> 事件。</p>
<p>注册了 <code>&apos;newListener&apos;</code> 事件的监听器会传入事件名与被添加的监听器的引用。</p>
<p>事实上，在添加监听器之前触发事件有一个微妙但重要的副作用：
在<code>&apos;newListener&apos;</code> 回调函数中, 一个监听器的名字如果和已有监听器名称相同, 则在被插入到EventEmitter实例的内部监听器数组时, 该监听器会被添加到其它同名监听器的前面。</p>
<pre><code class="lang-js">const myEmitter = new MyEmitter();
// 只处理一次，所以不会无限循环
myEmitter.once(&apos;newListener&apos;, (event, listener) =&gt; {
  if (event === &apos;event&apos;) {
    // 在开头插入一个新的监听器
    myEmitter.on(&apos;event&apos;, () =&gt; {
      console.log(&apos;B&apos;);
    });
  }
});
myEmitter.on(&apos;event&apos;, () =&gt; {
  console.log(&apos;A&apos;);
});
myEmitter.emit(&apos;event&apos;);
// 打印:
//   B
//   A
</code></pre>
<h3>&apos;removeListener&apos; 事件<span><a class="mark" href="#events_event_removelistener" id="events_event_removelistener">#</a></span></h3>
<div class="api_metadata">
<details class="changelog"><summary>版本历史</summary>
<table>
<tbody><tr><th>版本</th><th>变更</th></tr>
<tr><td>v6.1.0, v4.7.0</td>
<td><p>For listeners attached using <code>.once()</code>, the <code>listener</code> argument now yields the original listener function.</p>
</td></tr>
<tr><td>v0.9.3</td>
<td><p><span>新增于: v0.9.3</span></p>
</td></tr>
</tbody></table>
</details>
</div><ul>
<li><code>eventName</code> <span class="type">&lt;any&gt;</span> 事件名</li>
<li><code>listener</code> 
            <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function" class="type">&lt;Function&gt;</a> 事件句柄函数</li>
</ul>
<p><code>&apos;removeListener&apos;</code> 事件在 <code>listener</code> 被移除后触发。</p>
<h3>EventEmitter.listenerCount(emitter, eventName)<span><a class="mark" href="#events_eventemitter_listenercount_emitter_eventname" id="events_eventemitter_listenercount_emitter_eventname">#</a></span></h3>
<div class="api_metadata">
<span>新增于: v0.9.12</span><span>废弃于: v4.0.0</span>
</div><div class="api_stability api_stability_0"><a href="documentation.html#documentation_stability_index">稳定性: 0</a> - 废弃的: 使用 <a href="#events_emitter_listenercount_eventname"><code>emitter.listenerCount()</code></a> 代替。</div><p>A class method that returns the number of listeners for the given <code>eventName</code>
registered on the given <code>emitter</code>.</p>
<pre><code class="lang-js">const myEmitter = new MyEmitter();
myEmitter.on(&apos;event&apos;, () =&gt; {});
myEmitter.on(&apos;event&apos;, () =&gt; {});
console.log(EventEmitter.listenerCount(myEmitter, &apos;event&apos;));
// Prints: 2
</code></pre>
<h3>EventEmitter.defaultMaxListeners<span><a class="mark" href="#events_eventemitter_defaultmaxlisteners" id="events_eventemitter_defaultmaxlisteners">#</a></span></h3>
<div class="api_metadata">
<span>新增于: v0.11.2</span>
</div><p>每个事件默认可以注册最多 10 个监听器。
单个 <code>EventEmitter</code> 实例的限制可以使用 <a href="#events_emitter_setmaxlisteners_n"><code>emitter.setMaxListeners(n)</code></a> 方法改变。
所有 <code>EventEmitter</code> 实例的默认值可以使用 <code>EventEmitter.defaultMaxListeners</code> 属性改变。
如果这个值不是正数, 那将抛出 <code>TypeError</code>错误.</p>
<p>设置 <code>EventEmitter.defaultMaxListeners</code> 要谨慎，因为会影响所有 <code>EventEmitter</code> 实例，包括之前创建的。
因而，调用 <a href="#events_emitter_setmaxlisteners_n"><code>emitter.setMaxListeners(n)</code></a> 优先于 <code>EventEmitter.defaultMaxListeners</code>。</p>
<p>注意，这不是一个硬性限制。
<code>EventEmitter</code> 实例允许添加更多的监听器，但会向 <code>stderr</code> 输出跟踪警告，表明检测到一个可能的 EventEmitter 内存泄漏。
对于任何单个 <code>EventEmitter</code> 实例，<code>emitter.getMaxListeners()</code> 和 <code>emitter.setMaxListeners()</code> 方法可用于暂时地消除此警告：</p>
<pre><code class="lang-js">emitter.setMaxListeners(emitter.getMaxListeners() + 1);
emitter.once(&apos;event&apos;, () =&gt; {
  // 做些操作
  emitter.setMaxListeners(Math.max(emitter.getMaxListeners() - 1, 0));
});
</code></pre>
<p><a href="cli.html#cli_trace_warnings"><code>--trace-warnings</code></a> 命令行标志可用于显示此类警告的堆栈跟踪。</p>
<p>触发的警告可以使用 <a href="process.html#process_event_warning"><code>process.on(&apos;warning&apos;)</code></a> 检查，还有额外的 <code>emitter</code>、<code>type</code> 和 <code>count</code> 属性，分别代表事件触发器实例的引用、事件的名称、和附加的监听器的数量。其 <code>name</code> 属性设置为 <code>MaxListenersExceededWarning</code>。</p>
<h3>emitter.addListener(eventName, listener)<span><a class="mark" href="#events_emitter_addlistener_eventname_listener" id="events_emitter_addlistener_eventname_listener">#</a></span></h3>
<div class="api_metadata">
<span>新增于: v0.1.26</span>
</div><ul>
<li><code>eventName</code> <span class="type">&lt;any&gt;</span></li>
<li><code>listener</code> 
            <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function" class="type">&lt;Function&gt;</a></li>
</ul>
<p><code>emitter.on(eventName, listener)</code> 的别名。</p>
<h3>emitter.emit(eventName[, ...args])<span><a class="mark" href="#events_emitter_emit_eventname_args" id="events_emitter_emit_eventname_args">#</a></span></h3>
<div class="api_metadata">
<span>新增于: v0.1.26</span>
</div><ul>
<li><code>eventName</code> <span class="type">&lt;any&gt;</span></li>
<li><code>...args</code> <span class="type">&lt;any&gt;</span></li>
</ul>
<p>按监听器的注册顺序，同步地调用每个注册到名为 <code>eventName</code> 事件的监听器，并传入提供的参数。</p>
<p>如果事件有监听器，则返回 <code>true</code> ，否则返回 <code>false</code>。</p>
<h3>emitter.eventNames()<span><a class="mark" href="#events_emitter_eventnames" id="events_emitter_eventnames">#</a></span></h3>
<div class="api_metadata">
<span>新增于: v6.0.0</span>
</div><p>返回一个列出触发器已注册监听器的事件的数组。
数组中的值为字符串或符号。 </p>
<pre><code class="lang-js">const EventEmitter = require(&apos;events&apos;);
const myEE = new EventEmitter();
myEE.on(&apos;foo&apos;, () =&gt; {});
myEE.on(&apos;bar&apos;, () =&gt; {});

const sym = Symbol(&apos;symbol&apos;);
myEE.on(sym, () =&gt; {});

console.log(myEE.eventNames());
// 打印: [ &apos;foo&apos;, &apos;bar&apos;, Symbol(symbol) ]
</code></pre>
<h3>emitter.getMaxListeners()<span><a class="mark" href="#events_emitter_getmaxlisteners" id="events_emitter_getmaxlisteners">#</a></span></h3>
<div class="api_metadata">
<span>新增于: v1.0.0</span>
</div><p>返回 <code>EventEmitter</code> 当前的最大监听器限制值，该值可以通过 <a href="#events_emitter_setmaxlisteners_n"><code>emitter.setMaxListeners(n)</code></a> 设置或默认为 <a href="#events_eventemitter_defaultmaxlisteners"><code>EventEmitter.defaultMaxListeners</code></a>。</p>
<h3>emitter.listenerCount(eventName)<span><a class="mark" href="#events_emitter_listenercount_eventname" id="events_emitter_listenercount_eventname">#</a></span></h3>
<div class="api_metadata">
<span>新增于: v3.2.0</span>
</div><ul>
<li><code>eventName</code> <span class="type">&lt;any&gt;</span> 正在被监听的事件名</li>
</ul>
<p>返回正在监听名为 <code>eventName</code> 的事件的监听器的数量。</p>
<h3>emitter.listeners(eventName)<span><a class="mark" href="#events_emitter_listeners_eventname" id="events_emitter_listeners_eventname">#</a></span></h3>
<div class="api_metadata">
<details class="changelog"><summary>版本历史</summary>
<table>
<tbody><tr><th>版本</th><th>变更</th></tr>
<tr><td>v7.0.0</td>
<td><p>For listeners attached using <code>.once()</code> this returns the original listeners instead of wrapper functions now.</p>
</td></tr>
<tr><td>v0.1.26</td>
<td><p><span>新增于: v0.1.26</span></p>
</td></tr>
</tbody></table>
</details>
</div><ul>
<li><code>eventName</code> <span class="type">&lt;any&gt;</span></li>
</ul>
<p>返回名为 <code>eventName</code> 的事件的监听器数组的副本。</p>
<pre><code class="lang-js">server.on(&apos;connection&apos;, (stream) =&gt; {
  console.log(&apos;someone connected!&apos;);
});
console.log(util.inspect(server.listeners(&apos;connection&apos;)));
// 打印: [ [Function] ]
</code></pre>
<h3>emitter.on(eventName, listener)<span><a class="mark" href="#events_emitter_on_eventname_listener" id="events_emitter_on_eventname_listener">#</a></span></h3>
<div class="api_metadata">
<span>新增于: v0.1.101</span>
</div><ul>
<li><code>eventName</code> <span class="type">&lt;any&gt;</span> 事件名</li>
<li><code>listener</code> 
            <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function" class="type">&lt;Function&gt;</a> 回调函数</li>
</ul>
<p>添加 <code>listener</code> 函数到名为 <code>eventName</code> 的事件的监听器数组的末尾。
不会检查 <code>listener</code> 是否已被添加。
多次调用并传入相同的 <code>eventName</code> 和 <code>listener</code> 会导致 <code>listener</code> 被添加与调用多次。</p>
<pre><code class="lang-js">server.on(&apos;connection&apos;, (stream) =&gt; {
  console.log(&apos;有连接！&apos;);
});
</code></pre>
<p>返回一个 <code>EventEmitter</code> 引用，可以链式调用。</p>
<p>默认情况下，事件监听器会按照添加的顺序依次调用。
<code>emitter.prependListener()</code> 方法可用于将事件监听器添加到监听器数组的开头。</p>
<pre><code class="lang-js">const myEE = new EventEmitter();
myEE.on(&apos;foo&apos;, () =&gt; console.log(&apos;a&apos;));
myEE.prependListener(&apos;foo&apos;, () =&gt; console.log(&apos;b&apos;));
myEE.emit(&apos;foo&apos;);
// 打印:
//   b
//   a
</code></pre>
<h3>emitter.once(eventName, listener)<span><a class="mark" href="#events_emitter_once_eventname_listener" id="events_emitter_once_eventname_listener">#</a></span></h3>
<div class="api_metadata">
<span>新增于: v0.3.0</span>
</div><ul>
<li><code>eventName</code> <span class="type">&lt;any&gt;</span> 事件名</li>
<li><code>listener</code> 
            <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function" class="type">&lt;Function&gt;</a> 回调函数</li>
</ul>
<p>添加一个单次 <code>listener</code> 函数到名为 <code>eventName</code> 的事件。
下次触发 <code>eventName</code> 事件时，监听器会被移除，然后调用。</p>
<pre><code class="lang-js">server.once(&apos;connection&apos;, (stream) =&gt; {
  console.log(&apos;首次调用！&apos;);
});
</code></pre>
<p>返回一个 <code>EventEmitter</code> 引用，可以链式调用。</p>
<p>默认情况下，事件监听器会按照添加的顺序依次调用。
<code>emitter.prependOnceListener()</code> 方法可用于将事件监听器添加到监听器数组的开头。</p>
<pre><code class="lang-js">const myEE = new EventEmitter();
myEE.once(&apos;foo&apos;, () =&gt; console.log(&apos;a&apos;));
myEE.prependOnceListener(&apos;foo&apos;, () =&gt; console.log(&apos;b&apos;));
myEE.emit(&apos;foo&apos;);
// 打印:
//   b
//   a
</code></pre>
<h3>emitter.prependListener(eventName, listener)<span><a class="mark" href="#events_emitter_prependlistener_eventname_listener" id="events_emitter_prependlistener_eventname_listener">#</a></span></h3>
<div class="api_metadata">
<span>新增于: v6.0.0</span>
</div><ul>
<li><code>eventName</code> <span class="type">&lt;any&gt;</span> 事件名</li>
<li><code>listener</code> 
            <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function" class="type">&lt;Function&gt;</a> 回调函数</li>
</ul>
<p>添加 <code>listener</code> 函数到名为 <code>eventName</code> 的事件的监听器数组的开头。
不会检查 <code>listener</code> 是否已被添加。
多次调用并传入相同的 <code>eventName</code> 和 <code>listener</code> 会导致 <code>listener</code> 被添加与调用多次。</p>
<pre><code class="lang-js">server.prependListener(&apos;connection&apos;, (stream) =&gt; {
  console.log(&apos;有连接！&apos;);
});
</code></pre>
<p>返回一个 <code>EventEmitter</code> 引用，可以链式调用。</p>
<h3>emitter.prependOnceListener(eventName, listener)<span><a class="mark" href="#events_emitter_prependoncelistener_eventname_listener" id="events_emitter_prependoncelistener_eventname_listener">#</a></span></h3>
<div class="api_metadata">
<span>新增于: v6.0.0</span>
</div><ul>
<li><code>eventName</code> <span class="type">&lt;any&gt;</span> 事件名</li>
<li><code>listener</code> 
            <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function" class="type">&lt;Function&gt;</a> 回调函数</li>
</ul>
<p>添加一个单次 <code>listener</code> 函数到名为 <code>eventName</code> 的事件的监听器数组的开头。
下次触发 <code>eventName</code> 事件时，监听器会被移除，然后调用。</p>
<pre><code class="lang-js">server.prependOnceListener(&apos;connection&apos;, (stream) =&gt; {
  console.log(&apos;首次调用！&apos;);
});
</code></pre>
<p>返回一个 <code>EventEmitter</code> 引用，可以链式调用。</p>
<h3>emitter.removeAllListeners([eventName])<span><a class="mark" href="#events_emitter_removealllisteners_eventname" id="events_emitter_removealllisteners_eventname">#</a></span></h3>
<div class="api_metadata">
<span>新增于: v0.1.26</span>
</div><ul>
<li><code>eventName</code> <span class="type">&lt;any&gt;</span></li>
</ul>
<p>移除全部或指定 <code>eventName</code> 的监听器。</p>
<p>注意，在代码中移除其他地方添加的监听器是一个不好的做法，尤其是当 <code>EventEmitter</code> 实例是其他组件或模块（如 socket 或文件流）创建的。</p>
<p>返回一个 <code>EventEmitter</code> 引用，可以链式调用。</p>
<h3>emitter.removeListener(eventName, listener)<span><a class="mark" href="#events_emitter_removelistener_eventname_listener" id="events_emitter_removelistener_eventname_listener">#</a></span></h3>
<div class="api_metadata">
<span>新增于: v0.1.26</span>
</div><ul>
<li><code>eventName</code> <span class="type">&lt;any&gt;</span></li>
<li><code>listener</code> 
            <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function" class="type">&lt;Function&gt;</a></li>
</ul>
<p>从名为 <code>eventName</code> 的事件的监听器数组中移除指定的 <code>listener</code>。</p>
<pre><code class="lang-js">const callback = (stream) =&gt; {
  console.log(&apos;有连接！&apos;);
};
server.on(&apos;connection&apos;, callback);
// ...
server.removeListener(&apos;connection&apos;, callback);
</code></pre>
<p><code>removeListener</code> 最多只会从监听器数组里移除一个监听器实例。
如果任何单一的监听器被多次添加到指定 <code>eventName</code> 的监听器数组中，则必须多次调用 <code>removeListener</code> 才能移除每个实例。</p>
<p>注意，一旦一个事件被触发，所有绑定到它的监听器都会按顺序依次触发。
这意味着，在事件触发后、最后一个监听器完成执行前，任何 <code>removeListener()</code> 或 <code>removeAllListeners()</code> 调用都不会从 <code>emit()</code> 中移除它们。
随后的事件会像预期的那样发生。</p>
<pre><code class="lang-js">const myEmitter = new MyEmitter();

const callbackA = () =&gt; {
  console.log(&apos;A&apos;);
  myEmitter.removeListener(&apos;event&apos;, callbackB);
};

const callbackB = () =&gt; {
  console.log(&apos;B&apos;);
};

myEmitter.on(&apos;event&apos;, callbackA);

myEmitter.on(&apos;event&apos;, callbackB);

// callbackA 移除了监听器 callbackB，但它依然会被调用。
// 触发是内部的监听器数组为 [callbackA, callbackB]
myEmitter.emit(&apos;event&apos;);
// 打印:
//   A
//   B

// callbackB 被移除了。
// 内部监听器数组为 [callbackA]
myEmitter.emit(&apos;event&apos;);
// 打印:
//   A

</code></pre>
<p>因为监听器是使用内部数组进行管理的，所以调用它会改变在监听器被移除后注册的任何监听器的位置索引。
虽然这不会影响监听器的调用顺序，但意味着由 <code>emitter.listeners()</code> 方法返回的监听器数组副本需要被重新创建。</p>
<p>返回一个 <code>EventEmitter</code> 引用，可以链式调用。</p>
<h3>emitter.setMaxListeners(n)<span><a class="mark" href="#events_emitter_setmaxlisteners_n" id="events_emitter_setmaxlisteners_n">#</a></span></h3>
<div class="api_metadata">
<span>新增于: v0.3.5</span>
</div><ul>
<li><code>n</code> 
            <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type" class="type">&lt;integer&gt;</a></li>
</ul>
<p>默认情况下，如果为特定事件添加了超过 <code>10</code> 个监听器，则 <code>EventEmitter</code> 会打印一个警告。
此限制有助于寻找内存泄露。
但是，并不是所有的事件都要被限为 <code>10</code> 个。
<code>emitter.setMaxListeners()</code> 方法允许修改指定的 <code>EventEmitter</code> 实例的限制。
值设为 <code>Infinity</code>（或 <code>0</code>）表明不限制监听器的数量。</p>
<p>返回一个 <code>EventEmitter</code> 引用，可以链式调用。</p>

      </div>
    </div>

    <div id="column2" class="interior">
      <div id="intro" class="interior">
        <a href="/" title="Go back to the home page">
          Node.js 中文文档 | Node.js 中文网
        </a>
      </div>
      
        <!-- [start-include:_toc.md] -->
<ul>
<li><a href="documentation.html">关于本文档</a></li>
<li><a href="synopsis.html">用法与例子</a></li>
</ul>
<div class="line"></div>

<ul>
<li><a href="assert.html">断言测试</a></li>
<li><a href="async_hooks.html">异步钩子（Async Hooks）</a></li>
<li><a href="buffer.html">缓存（Buffer）</a></li>
<li><a href="addons.html">C++ 插件</a></li>
<li><a href="n-api.html">C/C++ 插件 - N-API</a></li>
<li><a href="child_process.html">子进程</a></li>
<li><a href="cluster.html">集群（Cluster）</a></li>
<li><a href="cli.html">命令行参数</a></li>
<li><a href="console.html">控制台（Console）</a></li>
<li><a href="crypto.html">加密（Crypto）</a></li>
<li><a href="debugger.html">调试器</a></li>
<li><a href="deprecations.html">废弃的 API</a></li>
<li><a href="dns.html">DNS</a></li>
<li><a href="domain.html">域（Domain）</a></li>
<li><a href="esm.html">ECMAScript 模块</a></li>
<li><a href="errors.html">错误（Errors）</a></li>
<li><a href="events.html">事件（Events）</a></li>
<li><a href="fs.html">文件系统</a></li>
<li><a href="globals.html">全局对象（Globals）</a></li>
<li><a href="http.html">HTTP</a></li>
<li><a href="http2.html">HTTP/2</a></li>
<li><a href="https.html">HTTPS</a></li>
<li><a href="inspector.html">检查工具（Inspector）</a></li>
<li><a href="intl.html">国际化</a></li>
<li><a href="modules.html">模块（Modules）</a></li>
<li><a href="net.html">网络（Net）</a></li>
<li><a href="os.html">操作系统（OS）</a></li>
<li><a href="path.html">路径（Path）</a></li>
<li><a href="perf_hooks.html">性能钩子（Performance Hooks）</a></li>
<li><a href="process.html">进程</a></li>
<li><a href="punycode.html">Punycode</a></li>
<li><a href="querystring.html">查询字符串</a></li>
<li><a href="readline.html">逐行读取</a></li>
<li><a href="repl.html">交互式解释器（REPL）</a></li>
<li><a href="stream.html">流（Stream）</a></li>
<li><a href="string_decoder.html">字符串解码</a></li>
<li><a href="timers.html">定时器（Timers）</a></li>
<li><a href="tls.html">安全传输层（TLS/SSL）</a></li>
<li><a href="tracing.html">事件跟踪（Tracing）</a></li>
<li><a href="tty.html">TTY</a></li>
<li><a href="dgram.html">UDP / 数据报</a></li>
<li><a href="url.html">URL</a></li>
<li><a href="util.html">工具集</a></li>
<li><a href="v8.html">V8</a></li>
<li><a href="vm.html">虚拟机（VM）</a></li>
<li><a href="zlib.html">压缩（ZLIB）</a></li>
</ul>
<div class="line"></div>

<ul>
<li><a href="https://github.com/nodejs/node">GitHub 仓库和问题跟踪</a></li>
<li><a href="https://groups.google.com/group/nodejs">邮件列表</a></li>
</ul>
<!-- [end-include:_toc.md] -->

      
    </div>
  </div>
  <script src="assets/sh_main.js"></script>
  <script src="assets/sh_javascript.min.js"></script>
  <script>highlight(undefined, undefined, 'pre');</script>
</body>
</html>
